class PowerCoverManager extends Actor;

var array<CoverLink> CoverList;
var float CoverDistanceThreshold;
//var array<PowerBlockingVolume> CoverBlockingVolumes;

event PostBeginPlay()
{
	local CoverLink firstLink;

	firstLink = WorldInfo.CoverList;

	while (firstLink != none)
	{
		CoverList.AddItem(firstLink);
		firstLink = firstLink.NextCoverLink;
	}

	//CreateBlockingVolumes();

	super.PostBeginPlay();
}

/*
function CreateBlockingVolumes()
{
	local CoverLink CurrentLink;
	local int i, j, Direction;
	local PowerBlockingVolume CoverBlockingVolume;
	local BoxSphereBounds CBVBounds;

	CBVBounds.BoxExtent = vect(10,10,0);

	for (i=0; i<CoverList.Length; i++)
	{
		CurrentLink = CoverList[i];
		for (j=0; j<CurrentLink.Slots.length; j++)
		{
			Direction = GetCoverDirection(CurrentLink, j);
			if (Direction != 0)
			{
				CoverBlockingVolume = Spawn(class'PowerBlockingVolume',,, CurrentLink.GetSlotLocation(j) + 10*GetSurfaceTangent(CurrentLink, j)/VSize(GetSurfaceTangent(CurrentLink, j)), CurrentLink.GetSlotRotation(j),,);
				CoverBlockingVolumes.AddItem(CoverBlockingVolume);
				`log("Added Blocking Volume for "$CurrentLink$" "$j);
			}
		}
	}
}
*/

function CoverLink GetClosestCoverLink(Vector pLocation)
{
	local float ClosestDist, TempDist;
	local CoverLink ClosestLink;
	local int i;

	ClosestDist = -1.0f;
	for (i=0; i<CoverList.Length; i++)
	{
		TempDist = VSize(pLocation - CoverList[i].Location);
		if ( (TempDist < ClosestDist) || (ClosestDist == -1.0f) )
		{
			ClosestDist = TempDist;
			ClosestLink = CoverList[i];
		}
	}

	return ClosestLink;
}

function int GetClosestCoverSlot(Pawn chkPawn, CoverLink PotentialCover)
{
	local int i;

	for (i=0; i<PotentialCover.Slots.Length; i++)
	{
		if ( VSize(chkPawn.Location - PotentialCover.GetSlotLocation(i)) < CoverDistanceThreshold )
		{
			if ( PotentialCover.IsValidClaim(chkPawn, i) )
			{
				//`log("[CoverManager] Slot found: "$i);
				return i;
			}
		}
	}

	//`log("[CoverManager] No slots found");
	return -1;
}

function vector GetSurfaceTangent(CoverLink CurrentCover, int CurrentSlot)
{
	local rotator HalfCircle, CoverBiNormal;
	local Vector CurrentSlotLocation, NextSlotLocation, Tangent;
	local Vector X, Y, Z;
	local int NextSlotIdx;

	CurrentSlotLocation = CurrentCover.GetSlotLocation(CurrentSlot);
	if ( CurrentCover.AllowLeftTransition(CurrentSlot) )
	{
		NextSlotIdx = CurrentCover.GetSlotIdxToLeft(CurrentSlot);
		NextSlotLocation = CurrentCover.GetSlotLocation(NextSlotIdx);
		Tangent = NextSlotLocation - CurrentSlotLocation;
	}
	else if ( CurrentCover.AllowRightTransition(CurrentSlot) )
	{
		NextSlotIdx = CurrentCover.GetSlotIdxToRight(CurrentSlot);
		NextSlotLocation = CurrentCover.GetSlotLocation(NextSlotIdx);
		Tangent = NextSlotLocation - CurrentSlotLocation;
	}
	else
	{
		HalfCircle = rot( 0, 16384, 0 );
		CoverBiNormal = Normalize( -1.0f*CurrentCover.GetSlotRotation(CurrentSlot) - HalfCircle );

		GetAxes(CoverBiNormal,X,Y,Z);
		Tangent = X;
	}
	return Tangent;
}

function bool CoverCrouchRequired(CoverLink CurrentCover, int CurrentSlotIdx)
{
	local CoverSlot CurrentSlot;

	CurrentSlot = CurrentCover.Slots[CurrentSlotIdx];

	if (CurrentSlot.CoverType == CT_MidLevel)
		return true;

	return false;
}

/**
 * Returns the direction-ness of a cover slot
 * -1 = Left slot
 * 0  = Center slot
 * 1  = Right slot
 */
function int GetCoverDirection(CoverLink CurrentCover, int CurrentSlotIdx)
{
	local CoverSlot CurrentSlot;

	CurrentSlot = CurrentCover.Slots[CurrentSlotIdx];

	if ( CurrentSlot.bLeanLeft )
		return -1;
	else if ( CurrentSlot.bLeanRight )
		return 1;
	
	return 0;
}

function string GetCoverInfo()
{
	local int i, j;
	local string Dump;
	local CoverLink temp;
	local CoverSlot tempslot;

	Dump = "";

	for (i=0; i<CoverList.Length; i++)
	{
		temp = CoverList[i];
		for (j = 0; j < temp.Slots.Length; j++)
		{
			tempslot = temp.Slots[j];
			Dump = Dump$"\n [CoverManager]CoverLink: "$temp$"|\n";
			Dump = Dump$"ID = "$j$", Left = "$temp.GetSlotIdxToLeft(j)$", Right = "$temp.GetSlotIdxToRight(j);
			Dump = Dump$"\nbCanSwatTurn_Left="$tempslot.bCanSwatTurn_Left;
			Dump = Dump$"\nbLeanLeft="$tempslot.bLeanLeft;
			Dump = Dump$"\nbCanCoverSlip_Left="$tempslot.bCanCoverSlip_Left;
			Dump = Dump$"\nbCanSwatTurn_Right="$tempslot.bCanSwatTurn_Right;
			Dump = Dump$"\nbLeanRight="$tempslot.bLeanRight;
			Dump = Dump$"\nbCanCoverSlip_Right="$tempslot.bCanCoverSlip_Right;
		}
	}
	return Dump;
}


DefaultProperties
{
	CoverDistanceThreshold=100.0f
}
